<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      let a = 1;
      let b = a;
      b = 3;
      // 基础数据类型(传值) 基本类型复制是值的复制，互相不受影响。下例中将 a 变量的值赋值给 b 变量后，因为基本类型变量是独立的所以 a 的改变不会影响 b 变量的值
      console.log(a, b);

      // 引用数据类型(传址) 赋值  不是浅拷贝  地址一样，指向了同一数据
      let person = {
        name: '张三',
        hobby: ['篮球', '棒球', '橄榄球'],
      };
      // let person1 = person;
      // person1.name = '李四';
      // console.log(person1.name);   //李四
      // console.log(person1.name);  //李四

      // 浅拷贝
      // 创建了一个新的对象 新 新的房间
      // 层次的理解
      // 拷贝值(如果属性是一般数据类型  拷贝的就是基本类型，  如果属性是引用数据类型，那么拷贝的就是 内存的地址)
      // 说的直白一点  如果碰到的是引用数据类型  那么拷贝前和拷贝后是互相影响的
      function shallowClone(source) {
        let newObj = {};
        for (let i in source) {
          if (source.hasOwnProperty(i)) {
            newObj[i] = source[i];
          }
        }
        return newObj;
      }
      let person1 = shallowClone(person);
      person1.name = '科比';
      console.log(person.name);
      console.log(person1.name);
      person1.hobby[1] = '冰球';
      console.log(person1.hobby[1]);
      console.log(person.hobby[1]);

      // 浅拷贝的方式一  展开语法
      let obj = {
        name: '后盾人',
        lessons: ['hobby', 'suxexu', 'kligh'],
      };
      let hd1 = { ...obj };
      hd1.name = 'hdcms';
      hd1.lessons[0] = 'cyl';
      console.log(obj);
      console.log(hd1);
      // 浅拷贝的方式二: Object.assign
      let obj1 = {
        name: '后盾人',
        lessons: ['hobby', 'suxexu', 'kligh'],
      };
      let hd2 = Object.assign({}, obj1);
      hd2.lessons[0] = '哈哈哈';
      console.log(obj1);
      console.log(hd2);
      // 浅拷贝的方式三
      let obj2 = {
        name: '后盾人',
        lessons: ['hobby', 'suxexu', 'kligh'],
      };
      let hd3 = {};
      for (let key in obj) {
        hd3[key] = obj2[key];
      }
      hd3.lessons[0] = '哈哈哈';
      console.log(obj2);
      console.log(hd3);
      // 浅拷贝的方式四 Array.prototype.concat
      //       const arr = [1, 2, {name: 'nordon'}];
      // const newArr = arr.concat();
      // newArr[2].name = 'wy';
      // console.log(arr);
      // console.log(newArr);
      // 5.Array.prototype.slice
      //       const arr = [1, 2, {name: 'nordon'}];
      // const newArr = arr.slice();
      // newArr[2].name = 'wy';

      // 深拷贝
      // 实现深拷贝的方法
      // 1.递归
      // 如果属性是引用数据类型，那么就会开辟一个新的房间
      function deepClone(source) {
        const targetObj = source.constructor === Array ? [] : {};
        for (let keys in source) {
          if (source.hasOwnProperty(keys)) {
            if (source[keys] && typeof source[keys] == 'object') {
              targetObj[keys] = source[keys].constructor == Array ? [] : {};
              targetObj[keys] = deepClone(source[keys]);
            } else {
              targetObj[keys] = source[keys];
            }
          }
        }
      }

      function copy(object) {
        let obj = object instanceof Array ? [] : {};
        for (const [k, v] of Object.entries(object)) {
          obj[k] = typeof v == 'object' ? copy(v) : v;
        }
        return obj;
      }

      // 2.函数库 lodash，提供 cloneDeep 实现
      // 3.JSON.parse(JSON.stringify(obj))
    </script>
  </body>
</html>
